<?php
/**
 * 优化版地区控制器
 * 解决大数据量传输问题，支持分层按需加载和数据压缩
 * 
 * @package app\controller\system
 * @author OA系统开发团队
 * @since 2.0.0
 */

declare (strict_types = 1);

namespace app\controller\system;

use app\BaseController;
use app\model\system\Region as RegionModel;
use think\facade\Cache;
use think\facade\Request;

class RegionOptimized extends BaseController
{
    /**
     * 缓存前缀
     */
    protected const CACHE_PREFIX = 'region:';
    
    /**
     * 缓存时间（秒）
     */
    protected const CACHE_TTL = 3600; // 1小时
    
    /**
     * 获取省份列表（精简版）
     * 
     * @return \think\response\Json
     */
    public function getProvinces(): \think\response\Json
    {
        $cacheKey = self::CACHE_PREFIX . 'provinces';
        
        try {
            // 尝试从缓存获取
            if ($cacheData = Cache::get($cacheKey)) {
                return $this->success($cacheData, '获取省份列表成功');
            }
            
            // 查询省份数据（仅必要字段）
            $provinces = RegionModel::field(['id', 'name', 'initial', 'pinyin'])
                ->where('level', 1)
                ->where('status', 1)
                ->order('initial', 'asc')
                ->order('name', 'asc')
                ->select()
                ->toArray();
            
            // 精简数据结构
            $result = array_map(function ($province) {
                return [
                    'id' => $province['id'],
                    'name' => $province['name'],
                    'initial' => $province['initial'],
                    'pinyin' => $province['pinyin']
                ];
            }, $provinces);
            
            // 缓存结果
            Cache::set($cacheKey, $result, self::CACHE_TTL);
            
            return $this->success($result, '获取省份列表成功');
            
        } catch (\Exception $e) {
            return $this->error('获取省份列表失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 获取城市列表（按省份分组）
     * 
     * @param int $provinceId 省份ID
     * @return \think\response\Json
     */
    public function getCities(int $provinceId): \think\response\Json
    {
        if ($provinceId <= 0) {
            return $this->error('省份ID必须是正整数', 400);
        }
        
        $cacheKey = self::CACHE_PREFIX . 'cities:' . $provinceId;
        
        try {
            // 尝试从缓存获取
            if ($cacheData = Cache::get($cacheKey)) {
                return $this->success($cacheData, '获取城市列表成功');
            }
            
            // 验证省份存在
            $province = RegionModel::where('id', $provinceId)
                ->where('level', 1)
                ->find();
                
            if (!$province) {
                return $this->error('省份不存在', 404);
            }
            
            // 查询城市数据
            $cities = RegionModel::field(['id', 'name', 'parent_id', 'initial', 'pinyin'])
                ->where('parent_id', $provinceId)
                ->where('level', 2)
                ->where('status', 1)
                ->order('initial', 'asc')
                ->order('name', 'asc')
                ->select()
                ->toArray();
            
            // 检查是否有子区域（区县）
            $cityIds = array_column($cities, 'id');
            $hasDistricts = [];
            if (!empty($cityIds)) {
                $districtCounts = RegionModel::where('parent_id', 'in', $cityIds)
                    ->where('level', 3)
                    ->where('status', 1)
                    ->group('parent_id')
                    ->column('COUNT(*) as count', 'parent_id');
                    
                foreach ($cityIds as $cityId) {
                    $hasDistricts[$cityId] = isset($districtCounts[$cityId]) && $districtCounts[$cityId] > 0;
                }
            }
            
            // 构建结果
            $result = array_map(function ($city) use ($hasDistricts) {
                return [
                    'id' => $city['id'],
                    'name' => $city['name'],
                    'parent_id' => $city['parent_id'],
                    'initial' => $city['initial'],
                    'pinyin' => $city['pinyin'],
                    'has_children' => $hasDistricts[$city['id']] ?? false
                ];
            }, $cities);
            
            // 缓存结果
            Cache::set($cacheKey, $result, self::CACHE_TTL);
            
            return $this->success($result, '获取城市列表成功');
            
        } catch (\Exception $e) {
            return $this->error('获取城市列表失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 获取区县列表（按城市分组）
     * 
     * @param int $cityId 城市ID
     * @return \think\response\Json
     */
    public function getDistricts(int $cityId): \think\response\Json
    {
        if ($cityId <= 0) {
            return $this->error('城市ID必须是正整数', 400);
        }
        
        $cacheKey = self::CACHE_PREFIX . 'districts:' . $cityId;
        
        try {
            // 尝试从缓存获取
            if ($cacheData = Cache::get($cacheKey)) {
                return $this->success($cacheData, '获取区县列表成功');
            }
            
            // 验证城市存在
            $city = RegionModel::where('id', $cityId)
                ->where('level', 2)
                ->find();
                
            if (!$city) {
                return $this->error('城市不存在', 404);
            }
            
            // 查询区县数据
            $districts = RegionModel::field(['id', 'name', 'parent_id', 'initial', 'pinyin'])
                ->where('parent_id', $cityId)
                ->where('level', 3)
                ->where('status', 1)
                ->order('initial', 'asc')
                ->order('name', 'asc')
                ->select()
                ->toArray();
            
            // 构建结果
            $result = array_map(function ($district) {
                return [
                    'id' => $district['id'],
                    'name' => $district['name'],
                    'parent_id' => $district['parent_id'],
                    'initial' => $district['initial'],
                    'pinyin' => $district['pinyin']
                ];
            }, $districts);
            
            // 缓存结果
            Cache::set($cacheKey, $result, self::CACHE_TTL);
            
            return $this->success($result, '获取区县列表成功');
            
        } catch (\Exception $e) {
            return $this->error('获取区县列表失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 搜索地区（支持模糊搜索）
     * 
     * @return \think\response\Json
     */
    public function search(): \think\response\Json
    {
        $keyword = Request::param('keyword', '');
        $level = (int)Request::param('level', 0);
        $limit = min(50, (int)Request::param('limit', 20));
        
        if (empty($keyword)) {
            return $this->error('搜索关键词不能为空', 400);
        }
        
        try {
            $query = RegionModel::field(['id', 'name', 'parent_id', 'level', 'initial', 'pinyin'])
                ->where('status', 1)
                ->where(function ($q) use ($keyword) {
                    $q->where('name', 'like', "%{$keyword}%")
                      ->whereOr('pinyin', 'like', "%{$keyword}%")
                      ->whereOr('initial', 'like', "%{$keyword}%");
                });
            
            if ($level > 0) {
                $query->where('level', $level);
            }
            
            $results = $query->order('level', 'asc')
                ->order('initial', 'asc')
                ->order('name', 'asc')
                ->limit($limit)
                ->select()
                ->toArray();
            
            // 获取完整的地址路径
            $enhancedResults = [];
            foreach ($results as $region) {
                $regionModel = new RegionModel();
                $regionModel->id = $region['id'];
                $regionModel->parent_id = $region['parent_id'];
                $regionModel->name = $region['name'];
                
                $region['full_address'] = $regionModel->getFullAddress();
                $enhancedResults[] = $region;
            }
            
            return $this->success($enhancedResults, '搜索成功');
            
        } catch (\Exception $e) {
            return $this->error('搜索失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 获取完整地址路径
     * 
     * @param int $id 地区ID
     * @return \think\response\Json
     */
    public function getFullPath(int $id): \think\response\Json
    {
        if ($id <= 0) {
            return $this->error('地区ID必须是正整数', 400);
        }
        
        try {
            $region = RegionModel::find($id);
            if (!$region) {
                return $this->error('地区不存在', 404);
            }
            
            $path = [];
            $current = $region;
            
            while ($current && $current->parent_id > 0) {
                array_unshift($path, [
                    'id' => $current->id,
                    'name' => $current->name,
                    'level' => $current->level
                ]);
                $current = $current->parent;
            }
            
            if ($current) {
                array_unshift($path, [
                    'id' => $current->id,
                    'name' => $current->name,
                    'level' => $current->level
                ]);
            }
            
            return $this->success([
                'target' => [
                    'id' => $region->id,
                    'name' => $region->name,
                    'level' => $region->level
                ],
                'path' => $path
            ], '获取地址路径成功');
            
        } catch (\Exception $e) {
            return $this->error('获取地址路径失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 批量获取地区信息
     * 
     * @return \think\response\Json
     */
    public function batch(): \think\response\Json
    {
        $ids = Request::param('ids', '');
        
        if (empty($ids)) {
            return $this->error('地区ID列表不能为空', 400);
        }
        
        try {
            $idArray = array_filter(array_map('intval', explode(',', $ids)));
            
            if (empty($idArray)) {
                return $this->error('无效的地区ID格式', 400);
            }
            
            $regions = RegionModel::field(['id', 'name', 'parent_id', 'level'])
                ->where('id', 'in', $idArray)
                ->where('status', 1)
                ->select()
                ->toArray();
            
            return $this->success($regions, '批量获取成功');
            
        } catch (\Exception $e) {
            return $this->error('批量获取失败: ' . $e->getMessage(), 500, 500);
        }
    }
    
    /**
     * 清除地区缓存
     * 
     * @return \think\response\Json
     */
    public function clearRegionCache(): \think\response\Json
    {
        try {
            Cache::tag('region')->clear();
            return $this->success('地区缓存清除成功');
        } catch (\Exception $e) {
            return $this->error('清除缓存失败: ' . $e->getMessage(), 500, 500);
        }
    }
}